/*
 * LCDBitmap
 * 
 * Licensed under the MIT License
 * 
 * Copyright (c) 2009 Jin Saburi (metalred.com),
 *                    BeInteractive! (www.be-interactive.org) and
 *                    Spark project  (www.libspark.org)
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * 
 */
package org.libspark.lcdbitmap
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.geom.Rectangle;
	
	/**
	 * Display the BitmapData like a LCD display.
	 *
	 * This is a class of <a href="http://blog.jactionscripters.com/2009/05/18/study-recreating-lcd-panels-trinitron-like-matrices/">
	 * Jin Saburi's effect</a>.
	 *
	 * @see http://blog.jactionscripters.com/2009/05/18/study-recreating-lcd-panels-trinitron-like-matrices/
	 */
	public class LCDBitmap extends Bitmap
	{
		/**
		 * Create a new instance of the LCDBitmap.
		 *
		 * @param	bitmapData	an instance of BitmapData you need to display.
		 * @param	tileSize	size of tile displays RGB color.
		 * @param	tileMargin	margin of each tiles
		 * @param	pixelSnapping	same as Bitmap class.
		 * @param	smoothing	same as Bitmap class.
		 */
		public function LCDBitmap(bitmapData:BitmapData, tileSize:uint = 3, tileMargin:uint = 1, pixelSnapping:String = 'auto', smoothing:Boolean = false)
		{
			_sourceBitmapData = bitmapData;
			_lcdBitmapData = new BitmapData(bitmapData.width * ((tileSize + tileMargin) * 3), bitmapData.height * ((tileSize + tileMargin) * 3), true, 0x00000000);
			super(_lcdBitmapData, pixelSnapping, smoothing);
			_tileSize = tileSize;
			_tileMargin = tileMargin;
			_tile = new Rectangle(0, 0, _tileSize, _tileSize);
			addEventListener(Event.ENTER_FRAME, renderHandler);
		}
		
		private var _sourceBitmapData:BitmapData;
		private var _lcdBitmapData:BitmapData;
		private var _tileSize:uint;
		private var _tileMargin:uint;
		private var _tile:Rectangle;
		
		private function renderHandler(e:Event):void
		{
			var source:BitmapData = _sourceBitmapData;
			var bitmap:BitmapData = _lcdBitmapData;
			bitmap.lock();
			bitmap.fillRect(bitmap.rect, 0x00000000);
			var sw:uint = source.width;
			var sh:uint = source.height;
			var size:uint = _tileSize;
			var margin:uint = _tileMargin;
			var tsize:uint = (size + margin);
			var psize:uint = tsize * 3;
			var tile:Rectangle = _tile;
			var px:uint, py:uint;
			var c:uint, r:uint, g:uint, b:uint;
			var x:uint, y:uint;
			for (x = 0; x < sw; ++x) {
				for (y = 0; y < sh; ++y) {
					c = source.getPixel(x, y);
					r = (c & 0xff0000) | 0xff000000;
					g = (c & 0x00ff00) | 0xff000000;
					b = (c & 0x0000ff) | 0xff000000;
					px = psize * x;
					py = psize * y;
					tile.x = px;
					tile.y = py;
					bitmap.fillRect(tile, r);
					tile.x = px + tsize;
					bitmap.fillRect(tile, g);
					tile.x = px + tsize * 2;
					bitmap.fillRect(tile, b);
					tile.x = px + margin;
					tile.y = py + tsize;
					bitmap.fillRect(tile, b);
					tile.x = px + margin + tsize;
					bitmap.fillRect(tile, r);
					tile.x = px + margin + tsize * 2;
					bitmap.fillRect(tile, g);
					tile.x = px + margin * 2;
					tile.y = py + tsize * 2;
					bitmap.fillRect(tile, g);
					tile.x = px + margin * 2 + tsize;
					bitmap.fillRect(tile, b);
					tile.x = px + margin * 2 + tsize * 2;
					bitmap.fillRect(tile, r);
				}
			}
			bitmap.unlock();
		}
	}
}